import * as Cesium from '@cesiumjs';
import MovableObjectLike from "../MovableObjectLike"
import RotatableObjectLike from "../RotatableObjectLike";
import {
  autorun,
  reaction,
  intercept,
  extendObservable,
  computed
} from 'mobx';
import {
  defineObjectProperty
} from "@g3x/utils";

/* 15 */
/***/
function registerPositionEditing(viewer, reactObject) {
  var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
    _ref$positionEditingP = _ref.positionEditingProperty,
    positionEditingProperty = _ref$positionEditingP === undefined ? 'positionEditing' : _ref$positionEditingP,
    _ref$positionProperty = _ref.positionProperty,
    positionProperty = _ref$positionProperty === undefined ? 'position' : _ref$positionProperty;

  extendObservable(reactObject, defineObjectProperty({}, positionEditingProperty, false));
  // reactObject.fromJsonFilterKeys.push(positionEditingProperty);

  var disposers = [];
  var movableObjectLike = void 0;

  if (positionProperty !== 'position') {
    disposers.push(function() {
      movableObjectLike = new MovableObjectLike(reactObject, positionProperty);
      return function() {
        movableObjectLike && movableObjectLike.destroy();
        movableObjectLike = undefined;
      };
    }());
  } else {
    movableObjectLike = reactObject;
  }

  disposers.push(autorun(function() {
    reactObject[positionEditingProperty] = viewer.interaction.movableObjectBinding.target === movableObjectLike;
  }));

  disposers.push(reaction(function() {
    return reactObject[positionEditingProperty];
  }, function() {
    if (!reactObject[positionEditingProperty] && earth.interaction.movableObjectBinding.target ===
      movableObjectLike) {
      earth.interaction.movableObjectBinding.target = undefined;
    } else if (reactObject[positionEditingProperty]) {
      earth.interaction.movableObjectBinding.target = movableObjectLike;
    }
  }, {
    fireImmediately: true
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerRotationEditing(earth, reactObject) {
  var _ref2 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
    _ref2$rotationEditing = _ref2.rotationEditingProperty,
    rotationEditingProperty = _ref2$rotationEditing === undefined ? 'rotationEditing' : _ref2$rotationEditing,
    _ref2$positionPropert = _ref2.positionProperty,
    positionProperty = _ref2$positionPropert === undefined ? 'position' : _ref2$positionPropert,
    _ref2$rotationPropert = _ref2.rotationProperty,
    rotationProperty = _ref2$rotationPropert === undefined ? 'rotation' : _ref2$rotationPropert;

  extendObservable(reactObject, defineObjectProperty({}, rotationEditingProperty, false));

  // reactObject.fromJsonFilterKeys.push(rotationEditingProperty);

  var disposers = [];
  var rotatableObjectLike = void 0;

  if (positionProperty !== 'position' || rotationProperty !== 'rotation') {
    disposers.push(function() {
      rotatableObjectLike = new RotatableObjectLike(reactObject, positionProperty,
        rotationProperty);
      return function() {
        rotatableObjectLike && rotatableObjectLike.destroy();
        rotatableObjectLike = undefined;
      };
    }());
  } else {
    rotatableObjectLike = reactObject;
  }

  disposers.push(autorun(function() {
    reactObject[rotationEditingProperty] = earth.interaction.rotatableObjectBinding.target ===
      rotatableObjectLike;
  }));

  disposers.push(reaction(function() {
    return reactObject[rotationEditingProperty];
  }, function() {
    if (!reactObject[rotationEditingProperty] && earth.interaction.rotatableObjectBinding.target ===
      rotatableObjectLike) {
      earth.interaction.rotatableObjectBinding.target = undefined;
    } else if (reactObject[rotationEditingProperty]) {
      earth.interaction.rotatableObjectBinding.target = rotatableObjectLike;
    }
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerHeightEditing(earth, reactObject, _ref3) {
  var _ref3$positionHeightE = _ref3.positionHeightEditing,
    positionHeightEditing = _ref3$positionHeightE === undefined ? 'heightEditing' : _ref3$positionHeightE,
    _ref3$positionPropert = _ref3.positionProperty,
    positionProperty = _ref3$positionPropert === undefined ? 'position' : _ref3$positionPropert;

  extendObservable(reactObject, defineObjectProperty({}, positionHeightEditing, false));
  reactObject.fromJsonFilterKeys.push(positionHeightEditing);

  var disposers = [];

  var movableObjectLike = void 0;

  if (positionProperty !== 'position') {
    disposers.push(function() {
      movableObjectLike = new _MovableObjectLike2.default(reactObject, positionProperty);
      return function() {
        movableObjectLike && movableObjectLike.destroy();
        movableObjectLike = undefined;
      };
    }());
  } else {
    movableObjectLike = reactObject;
  }

  disposers.push(autorun(function() {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.heightEditingBinding) {
      return;
    }

    reactObject[positionHeightEditing] = earth.interaction.heightEditingBinding.target ===
      movableObjectLike;
  }));

  function assignTarget(reactObject, positionHeightEditing) {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.heightEditingBinding) {
      return;
    }

    if (!reactObject[positionHeightEditing] && earth.interaction.heightEditingBinding.target ===
      movableObjectLike) {
      earth.interaction.heightEditingBinding.target = undefined;
    } else if (reactObject[positionHeightEditing]) {
      earth.interaction.heightEditingBinding.target = movableObjectLike;
    }
  };

  assignTarget(reactObject, positionHeightEditing);

  disposers.push(reaction(function() {
    return reactObject[positionHeightEditing];
  }, function() {
    assignTarget(reactObject, positionHeightEditing);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerPolygonCreatingWithHeight(earth, reactObject, _ref4) {
  var _ref4$polygonCreating = _ref4.polygonCreatingWithHeight,
    polygonCreatingWithHeight = _ref4$polygonCreating === undefined ? 'creatingWithHeight' :
    _ref4$polygonCreating;

  extendObservable(reactObject, defineObjectProperty({}, polygonCreatingWithHeight, false));
  // reactObject.fromJsonFilterKeys.push(polygonCreatingWithHeight);

  var disposers = [];

  disposers.push(autorun(function() {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.flattenedPolygonCreatingBinding) {
      return;
    }

    reactObject[polygonCreatingWithHeight] = earth.interaction.flattenedPolygonCreatingBinding.target ===
      reactObject;
  }));

  function assignTarget(reactObject, polygonCreatingWithHeight) {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.flattenedPolygonCreatingBinding) {
      return;
    }

    if (!reactObject[polygonCreatingWithHeight] && earth.interaction.flattenedPolygonCreatingBinding
      .target === reactObject) {
      earth.interaction.flattenedPolygonCreatingBinding.target = undefined;
    } else if (reactObject[polygonCreatingWithHeight]) {
      earth.interaction.flattenedPolygonCreatingBinding.target = reactObject;
    }
  };

  assignTarget(reactObject, polygonCreatingWithHeight);

  disposers.push(reaction(function() {
    return reactObject[polygonCreatingWithHeight];
  }, function() {
    assignTarget(reactObject, polygonCreatingWithHeight);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerPolygonCreating(earth, reactObject, _ref5) {
  var _ref5$polygonCreating = _ref5.polygonCreating,
    polygonCreating = _ref5$polygonCreating === undefined ? 'creating' : _ref5$polygonCreating;

  extendObservable(reactObject, defineObjectProperty({}, polygonCreating, false));
  reactObject.fromJsonFilterKeys.push(polygonCreating);

  var disposers = [];

  disposers.push(autorun(function() {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.creatingPolygonBinding) {
      return;
    }

    reactObject[polygonCreating] = earth.interaction.creatingPolygonBinding.target === reactObject;
  }));

  function assignTarget(reactObject, polygonCreating) {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.creatingPolygonBinding) {
      return;
    }

    if (!reactObject[polygonCreating] && earth.interaction.creatingPolygonBinding.target === reactObject) {
      earth.interaction.creatingPolygonBinding.target = undefined;
    } else if (reactObject[polygonCreating]) {
      earth.interaction.creatingPolygonBinding.target = reactObject;
    }
  };

  assignTarget(reactObject, polygonCreating);

  disposers.push(reaction(function() {
    return reactObject[polygonCreating];
  }, function() {
    assignTarget(reactObject, polygonCreating);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerPolygonEditing(earth, reactObject, _ref6) {
  var _ref6$polygonEditingP = _ref6.polygonEditingProperty,
    polygonEditingProperty = _ref6$polygonEditingP === undefined ? 'polygonEditing' : _ref6$polygonEditingP;

  // (0, _mobx.extendObservable)(reactObject, (0, _defineProperty3.default)({}, polygonEditingProperty, false));
  extendObservable(reactObject, defineObjectProperty({}, polygonEditingProperty, false));
  // reactObject.fromJsonFilterKeys.push(polygonEditingProperty);

  var disposers = [];

  disposers.push(autorun(function() {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.editingPolygonBinding) {
      return;
    }

    reactObject[polygonEditingProperty] = earth.interaction.editingPolygonBinding.target === reactObject;
  }));

  function assignTarget(reactObject, polygonEditingProperty) {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.editingPolygonBinding) {
      return;
    }

    if (!reactObject[polygonEditingProperty] && earth.interaction.editingPolygonBinding.target ===
      reactObject) {
      earth.interaction.editingPolygonBinding.target = undefined;
    } else if (reactObject[polygonEditingProperty]) {
      earth.interaction.editingPolygonBinding.target = reactObject;
    }
  };

  assignTarget(reactObject, polygonEditingProperty);

  disposers.push(reaction(function() {
    return reactObject[polygonEditingProperty];
  }, function() {
    assignTarget(reactObject, polygonEditingProperty);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerPolylineCreating(earth, reactObject, _ref7) {
  var _ref7$polylineCreatin = _ref7.polylineCreatingProperty,
    polylineCreatingProperty = _ref7$polylineCreatin === undefined ? 'creating' : _ref7$polylineCreatin;

  // (0, _mobx.extendObservable)(reactObject, (0, _defineProperty3.default)({}, polylineCreatingProperty, false));
  extendObservable(reactObject, defineObjectProperty({}, polylineCreatingProperty, false));
  reactObject.fromJsonFilterKeys.push(polylineCreatingProperty);

  var disposers = [];

  disposers.push(autorun(function() {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction) {
      return;
    }

    reactObject[polylineCreatingProperty] = earth.interaction.creatingPolylineBinding.target ===
      reactObject;
  }));

  function assignTarget(reactObject, polylineCreatingProperty) {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.creatingPolylineBinding) {
      return;
    }

    if (!reactObject[polylineCreatingProperty] && earth.interaction.creatingPolylineBinding.target ===
      reactObject) {
      earth.interaction.creatingPolylineBinding.target = undefined;
    } else if (reactObject[polylineCreatingProperty]) {
      earth.interaction.creatingPolylineBinding.target = reactObject;
    }
  };

  assignTarget(reactObject, polylineCreatingProperty);

  disposers.push(reaction(function() {
    return reactObject[polylineCreatingProperty];
  }, function() {
    assignTarget(reactObject, polylineCreatingProperty);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerPolylineEditing(earth, reactObject, _ref8) {
  var _ref8$polylineEditing = _ref8.polylineEditingProperty,
    polylineEditingProperty = _ref8$polylineEditing === undefined ? 'polylineEditing' : _ref8$polylineEditing;

  // (0, _mobx.extendObservable)(reactObject, (0, _defineProperty3.default)({}, polylineEditingProperty, false));
  extendObservable(reactObject, defineObjectProperty({}, polylineEditingProperty, false));
  reactObject.fromJsonFilterKeys.push(polylineEditingProperty);

  var disposers = [];

  disposers.push(autorun(function() {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.editingPolylineBinding) {
      return;
    }

    reactObject[polylineEditingProperty] = earth.interaction.editingPolylineBinding.target ===
      reactObject;
  }));

  function assignTarget(reactObject, polylineEditingProperty) {
    // interaction有可能还不存在
    if (!earth.interaction || !earth.interaction.editingPolylineBinding) {
      return;
    }

    if (!reactObject[polylineEditingProperty] && earth.interaction.editingPolylineBinding.target ===
      reactObject) {
      earth.interaction.editingPolylineBinding.target = undefined;
    } else if (reactObject[polylineEditingProperty]) {
      earth.interaction.editingPolylineBinding.target = reactObject;
    }
  };

  assignTarget(reactObject, polylineEditingProperty);

  disposers.push(reaction(function() {
    return reactObject[polylineEditingProperty];
  }, function() {
    assignTarget(reactObject, polylineEditingProperty);
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

function registerPositionPicking(earth, reactObject) {
  var _ref9 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
    _ref9$positionPicking = _ref9.positionPickingProperty,
    positionPickingProperty = _ref9$positionPicking === undefined ? 'positionPicking' : _ref9$positionPicking,
    _ref9$positionPropert = _ref9.positionProperty,
    positionProperty = _ref9$positionPropert === undefined ? 'position' : _ref9$positionPropert;

  // (0, _mobx.extendObservable)(reactObject, (0, _defineProperty3.default)({}, positionPickingProperty, false));
  extendObservable(reactObject, defineObjectProperty({}, positionPickingProperty, false));
  reactObject.fromJsonFilterKeys.push(positionPickingProperty);

  var disposers = [];
  var movableObjectLike = void 0;

  if (positionProperty !== 'position') {
    disposers.push(function() {
      movableObjectLike = new _MovableObjectLike2.default(reactObject, positionProperty);
      return function() {
        movableObjectLike && movableObjectLike.destroy();
        movableObjectLike = undefined;
      };
    }());
  } else {
    movableObjectLike = reactObject;
  }

  disposers.push(autorun(function() {
    reactObject[positionPickingProperty] = earth.interaction.positionPickingBinding.target ===
      movableObjectLike;
  }));

  disposers.push(reaction(function() {
    return reactObject[positionPickingProperty];
  }, function() {
    if (!reactObject[positionPickingProperty] && earth.interaction.positionPickingBinding.target ===
      movableObjectLike) {
      earth.interaction.positionPickingBinding.target = undefined;
    } else if (reactObject[positionPickingProperty]) {
      earth.interaction.positionPickingBinding.target = movableObjectLike;
    }
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

// 和以往的方式不同，通过func来操作，而不是xxxobjectLike的方式，这样更灵活！
// TODO(vtxf): 以后可以根据此方式来改造之前的模式
var defaultCameraTrackingFunc = function defaultCameraTrackingFunc(tracking) {
  var disposers = [];
  disposers.push((0, _track2.default)(tracking, 'position', target, 'position'));
  disposers.push((0, _track2.default)(tracking, 'rotation', target, 'rotation'));
  disposers.push((0, _track2.default)(tracking, 'viewDistance', target, 'viewDistance'));
  earth.camera.tracking.isCameraLike = target.isCameraLike;

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
};

function registerCameraTracking(earth, reactObject) {
  var _ref10 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
    _ref10$cameraAttached = _ref10.cameraAttachedProperty,
    cameraAttachedProperty = _ref10$cameraAttached === undefined ? 'cameraAttached' : _ref10$cameraAttached,
    _ref10$cameraAttached2 = _ref10.cameraAttachedFunc,
    cameraAttachedFunc = _ref10$cameraAttached2 === undefined ? defaultCameraTrackingFunc :
    _ref10$cameraAttached2;

  // (0, _mobx.extendObservable)(reactObject, (0, _defineProperty3.default)({}, cameraAttachedProperty, false));
  extendObservable(reactObject, defineObjectProperty({}, cameraAttachedProperty, false));
  // reactObject.fromJsonFilterKeys.push(cameraAttachedProperty);

  reactObject.cameraTrackingFunc = cameraAttachedFunc;

  var disposers = [];

  disposers.push(autorun(function() {
    reactObject[cameraAttachedProperty] = earth.interaction.cameraTrackingBinding.target === reactObject;
  }));

  disposers.push(reaction(function() {
    return reactObject[cameraAttachedProperty];
  }, function() {
    if (!reactObject[cameraAttachedProperty] && earth.interaction.cameraTrackingBinding.target ===
      reactObject) {
      earth.interaction.cameraTrackingBinding.target = undefined;
    } else if (reactObject[cameraAttachedProperty]) {
      earth.interaction.cameraTrackingBinding.target = reactObject;
    }
  }));

  return function() {
    disposers.forEach(function(d) {
      return d();
    });
    disposers.length = 0;
  };
}

export default {
  registerPositionEditing,
  registerRotationEditing,
  registerPolygonCreatingWithHeight,
  registerPolygonCreating,
  registerPolygonEditing,
  registerPolylineCreating,
  registerPolylineEditing,
  registerPositionPicking,
  registerCameraTracking,
  registerHeightEditing
};
